`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: Boston University
// Engineer: Zafar M. Takhirov
//
// Create Date:    
// Design Name: 
// Module Name:    vga_display
// Project Name: 
// Target Devices: xc6slx16-3csg324
// Tool versions: 
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module vga_display(rst, clk, reset, difficulty, button1, button2, button3, button4, R, G, B, HS, VS);
   input rst;   
   input clk;		
	input reset;
	input [1:0] difficulty;
	input button1, button2, button3, button4;
	reg [1:0] LEDclkspeed, DBclkspeed;
   
      output reg [2:0] R, G;

   output reg [1:0] B;
   
   // Synchronization signals

   output HS;

   output VS;
   
   // controls:

   wire [10:0] hcount, vcount;    		

   wire blank;                       		// signal to indicate the current coordinate is blank

   wire figure1, figure2, figure3, figure4; 	   // the figure you want to display

	wire o_clk, o_clk2, o_clk3, o_clk4;
	
	wire [3:0] rand1, rand2, rand3, rand4;
	reg [3:0] seed1, seed2, seed3, seed4;
	reg start1, start2, start3, start4, start5, start6, start7;
	wire step1, step2, step3, step4;
	reg [7:0] score, scoretwo;
	reg [1:0] state, nextstate;
	wire score1, score2, score3, score4;
	reg [9:0] M1,M2,M3,M4;
	reg [2:0] column1, column2, column3, column4;

	reg [100:0] figcount;
	reg [19:0] scorecount;
	
	LFSR randomline1(.clk(clk),.out(rand1),.reset(reset),.M(M1),.seed(seed1));
	LFSR randomline2(.clk(clk),.out(rand2),.reset(reset),.M(M2),.seed(seed2));
	LFSR randomline3(.clk(clk),.out(rand3),.reset(reset),.M(M3),.seed(seed3));
	LFSR randomline4(.clk(clk),.out(rand4),.reset(reset),.M(M4),.seed(seed4));


   parameter I = 2;    // parameter for clock division

   reg clk_25Mhz;

   reg [I-1:0] count;


   always @ (posedge clk) begin
       count <= count + 1'b1;

       clk_25Mhz <= count[1];

   end

   vga_controller vc_0(
       .rst(rst),
       .pixel_clk(clk_25Mhz),
       .HS(HS),
       .VS(VS),
       .hcounter(hcount),
       .vcounter(vcount),
       .blank(blank)
       );
        

   //
   ClockDivider CD_0(clk, o_clk, difficulty);   
	
	   debouncer db1 (
		.button(button1), 
		.clk(clk), 
		.i_increment(step1));
		
		debouncer db2 (
		.button(button2), 
		.clk(clk), 
		.i_increment(step2));
		
		debouncer db3 (
		.button(button3), 
		.clk(clk), 
		.i_increment(step3));
		
		debouncer db4 (
		.button(button4), 
		.clk(clk), 
		.i_increment(step4));


	//score
	scoring sco1(o_clk3, rand1, rand2, rand3, rand4, M1, M2, M3, M4, 
			step1, column1, score1);
	scoring sco2(o_clk3, rand1, rand2, rand3, rand4, M1, M2, M3, M4, 
			step2, column2, score2);
	scoring sco3(o_clk3, rand1, rand2, rand3, rand4, M1, M2, M3, M4, 
			step3, column3, score3);
	scoring sco4(o_clk3, rand1, rand2, rand3, rand4, M1, M2, M3, M4, 
			step4, column4, score4);
	
	
		//four stable coloumns at the bottom
	assign figure0_1 = ~blank & (hcount==48 & vcount>=388 & vcount<=432
		|| hcount==152 & vcount>=388 & vcount<=432
		|| vcount==388 & hcount>=48 & hcount<=152
		|| vcount==432 & hcount>=48 & hcount<=152);
		
	assign figure0_2 = ~blank & (hcount==198 & vcount>=388 & vcount<=432
		|| hcount==302 & vcount>=388 & vcount<=432
		|| vcount==388 & hcount>=198 & hcount<=302
		|| vcount==432 & hcount>=198 & hcount<=302);
		
	assign figure0_3 = ~blank & (hcount==348 & vcount>=388 & vcount<=432
		|| hcount==452 & vcount>=388 & vcount<=432
		|| vcount==388 & hcount>=348 & hcount<=452
		|| vcount==432 & hcount>=348 & hcount<=452);
		
	assign figure0_4 = ~blank & (hcount==498 & vcount>=388 & vcount<=432
		|| hcount==602 & vcount>=388 & vcount<=432
		|| vcount==388 & hcount>=498 & hcount<=602
		|| vcount==432 & hcount>=498 & hcount<=602);
	
				
	//four boxes graphics
	//first column
	assign figure1 = ~blank & (hcount>=50 & hcount<=150 & vcount>=M1-40 & vcount<=M1); 
	assign figure2 = ~blank & (hcount>=50 & hcount<=150 & vcount>=M2-40 & vcount<=M2);
	assign figure3 = ~blank & (hcount>=50 & hcount<=150 & vcount>=M3-40 & vcount<=M3);
	assign figure4 = ~blank & (hcount>=50 & hcount<=150 & vcount>=M4-40 & vcount<=M4); 

	//second column
	assign figure8 = ~blank & (hcount>=200 & hcount<=300 & vcount>=M1-40 & vcount<=M1); 
	assign figure9 = ~blank & (hcount>=200 & hcount<=300 & vcount>=M2-40 & vcount<=M2);
	assign figure10 = ~blank & (hcount>=200 & hcount<=300 & vcount>=M3-40 & vcount<=M3);
	assign figure11 = ~blank & (hcount>=200 & hcount<=300 & vcount>=M4-40 & vcount<=M4); 

	//third column
	assign figure15 = ~blank & (hcount>=350 & hcount<=450 & vcount>=M1-40 & vcount<=M1); 
	assign figure16 = ~blank & (hcount>=350 & hcount<=450 & vcount>=M2-40 & vcount<=M2);
	assign figure17 = ~blank & (hcount>=350 & hcount<=450 & vcount>=M3-40 & vcount<=M3);
	assign figure18 = ~blank & (hcount>=350 & hcount<=450 & vcount>=M4-40 & vcount<=M4); 

	//fourth column
	assign figure22 = ~blank & (hcount>=500 & hcount<=600 & vcount>=M1-40 & vcount<=M1); 
	assign figure23 = ~blank & (hcount>=500 & hcount<=600 & vcount>=M2-40 & vcount<=M2);
	assign figure24 = ~blank & (hcount>=500 & hcount<=600 & vcount>=M3-40 & vcount<=M3);
	assign figure25 = ~blank & (hcount>=500 & hcount<=600 & vcount>=M4-40 & vcount<=M4); 
	
	//initialize values
	initial begin
		DBclkspeed = 2'b00;
	
		M1 = 10'd460;
		M2 = 10'd460;
		M3 = 10'd460;
		M4 = 10'd460;
		
		seed2 = 4'b1000;
		//seed7 = 4'b0100;
		//seed5 = 4'b0010;
		seed3 = 4'b0001;
		seed1 = 4'b1100;
		seed4 = 4'b0011;
		//seed6 = 4'b0110;
		
		start1 = 1'b0;
		start2 = 1'b0;
		start3 = 1'b0;
		start4 = 1'b0;
		
		column1 = 3'b001;
		column2 = 3'b010;
		column3 = 3'b011;
		column4 = 3'b100;
		
		score = 0;
	end


   //block movement & spacing
	always @(posedge o_clk) begin
		 if (reset==1) begin
				figcount = 101'd350;
				start1 = 0;
				start2 = 0;
				start3 = 0;
				start4 = 0;

				M1 = 10'd100;
				M2 = 10'd100;
				M3 = 10'd100;
				M4 = 10'd100;
		 end
		 if (M1==430) begin
			  M1 = 140;
		 end
		 if (M2==430) begin
			  M2 = 140;
		 end
		 if (M3==430) begin
			  M3 = 140;
		 end
		 if (M4==430) begin
			  M4 = 140;
		 end
		 
		 
		if (figcount < 350 && start1 == 0) begin
			start1 = 1;
		end
		if (figcount < 250 && start2 == 0) begin
			start2 = 1;
		end
		if (figcount < 150 && start3 == 0) begin
			start3 = 1;
		end
		if (figcount <  50 && start4 == 0) begin
			start4 = 1;
		end


		if (start1 == 1) begin
			M1 = M1 + 1'b1;
		end
		if (start2 == 1) begin
			M2 = M2 + 1'b1;
		end
		if (start3 == 1) begin
			M3 = M3 + 1'b1;
		end
		if (start4 == 1) begin
			M4 = M4 + 1'b1;
		end

		figcount = figcount - 1'b1;
	end

	
   // send colors to VGA:
   always @ (posedge clk) begin
         if (figure0_1) begin   
			if (button1==1) begin
				R = 1;
				G = 4;
				B = 1;
							end else begin
				R = 2;
				G = 2;	
				B = 1;
			end
		//second goal post
		end else if (figure0_2) begin   
			if (button2==1) begin
				R = 1;
				G = 4;
				B = 1;
							end else begin
				R = 2;
				G = 2;	
				B = 1;

			end
		//third goalpost
		end else if (figure0_3) begin   
			if (button3==1) begin
				R = 1;
				G = 4;
				B = 1;
			end else begin
				R = 2;
				G = 2;	
				B = 1;
			end
		//fourth goal post
		end else if (figure0_4) begin   
			if (button4==1) begin
				R = 1;
				G = 4;
				B = 1;
			end else begin
				R = 2;
				G = 2;	
				B = 1;
			end
			
		//moving figures start here:
      end else if ((figure1 && rand1[0]==1) || (figure2 && rand2[0]==1) ||
		(figure3 && rand3[0]==1) || (figure4 && rand4[0]==1)) begin
		   R = 0;	// first column contains green boxes
         G = 3;
         B = 0;
		end else if ((figure8 && rand1[1]==1) || (figure9 && rand2[1]==1) ||
		(figure10 && rand3[1]==1) || (figure11 && rand4[1]==1) ) begin
			R = 3;	// these are all red
         G = 0;
         B = 0;
		end else if ((figure15 && rand1[2]==1) || (figure16 && rand2[2]==1) ||
		(figure17 && rand3[2]==1) || (figure18 && rand4[2]==1)) begin
		   R = 4;	// yellow
         G = 3;
         B = 0;
		end else if ((figure22 && rand1[3]==1) || (figure23 && rand2[3]==1) ||
		(figure24 && rand3[3]==1) || (figure25 && rand4[3]==1) ) begin
			R = 0;	// blue
			G = 0;
			B = 2;
		end else begin    // if you are outside the valid region
         R = 0;	// display black
         G = 0;
         B = 0;
      end
   end
endmodule
